/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.editors.workbench;

import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.identity.GetStudioRolesCmd;
import cn.easyplatform.studio.cmd.identity.GetStudioRoleslikeCmd;
import cn.easyplatform.studio.cmd.identity.UpdateStudioRoleCmd;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.utils.StudioUtil;
import cn.easyplatform.studio.utils.WebUtils;
import cn.easyplatform.studio.vos.RoleVo;
import cn.easyplatform.studio.web.editors.AbstractPanelEditor;
import cn.easyplatform.studio.web.layout.WorkbenchController;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zul.*;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public class RoleEditor extends AbstractPanelEditor {

    private Listbox roleGrid;

    private Textbox key;

    private Textbox name;

    private Textbox desp;

    private Tree access;

    private Checkbox checkAll;

    private Checkbox checkRev;

    private RoleVo selectedRole;

    private Bandbox rolesSearch;

    private String val;

    public RoleEditor(WorkbenchController workbench, String id) {
        super(workbench, id);
    }

    @Override
    public void create(Object... args) {
        Idspace is = createPanel(Labels.getLabel("menu.studio.role"), "~./images/group.png", "~./include/editor/workbench/role.zul");
        for (Component comp : is.getFellows()) {
            if (comp.getId().equals("workbenchRole_listbox_roles"))
                roleGrid = (Listbox) comp;
            else if (comp.getId().equals("workbenchRole_textbox_id"))
                key = (Textbox) comp;
            else if (comp.getId().equals("workbenchRole_textbox_name"))
                name = (Textbox) comp;
            else if (comp.getId().equals("workbenchRole_textbox_desp"))
                desp = (Textbox) comp;
            else if (comp.getId().equals("workbenchRole_tree_access")) {
                access = (Tree) comp;
            } else if (comp.getId().equals("workbenchRole_checkbox_checkAll")) {
                checkAll = (Checkbox) comp;
                checkAll.addEventListener(Events.ON_CHECK, this);
            } else if (comp.getId().equals("workbenchRole_bandbox_rolesSearch")) {
                rolesSearch = (Bandbox) comp;
                rolesSearch.addEventListener(Events.ON_OPEN, this);
                rolesSearch.addEventListener(Events.ON_OK, this);
            } else if (comp.getId().equals("workbenchRole_checkbox_checkRev")) {
                checkRev = (Checkbox) comp;
                checkRev.addEventListener(Events.ON_CHECK, this);
            } else if (comp instanceof Button) {
                String AuthorizedKey = null;
                if (comp.getId().equals("workbenchRole_button_studioRoleAdd"))
                    AuthorizedKey = "studioRoleAdd";
                else if (comp.getId().equals("workbenchRole_button_studioRoleDelete"))
                    AuthorizedKey = "studioRoleDelete";
                else if (comp.getId().equals("workbenchRole_button_studioRoleEdit"))
                    AuthorizedKey = "studioRoleEdit";
                boolean isAuthorized = Contexts.getUser().isAuthorized(AuthorizedKey);
                if (isAuthorized)
                    comp.addEventListener(Events.ON_CLICK, this);
                else
                    ((Button) comp).setDisabled(true);
            }
        }
        List<RoleVo> roles = StudioApp.execute(new GetStudioRolesCmd());
        redraw(roles);
        selectedRole = new RoleVo();
        selectedRole.setCode('C');
    }

    private void redraw(List<RoleVo> roles) {
        roleGrid.getItems().clear();
        for (RoleVo role : roles) {
            Listitem row = new Listitem();
            row.setValue(role);
            row.appendChild(new Listcell(role.getId()));
            row.appendChild(new Listcell(role.getName()));
            row.appendChild(new Listcell(role.getDesp()));
            row.addEventListener(Events.ON_CLICK, this);
            if (selectedRole != null && selectedRole.getCode() == 'U' && selectedRole.getId().equals(role.getId())) {
                row.setSelected(true);
            }
            roleGrid.appendChild(row);
        }
    }

    private void setValue() {
        checkAll.setChecked(false);
        checkRev.setChecked(false);
        key.setValue(selectedRole.getId());
        name.setValue(selectedRole.getName());
        desp.setValue(selectedRole.getDesp());
        Iterator<Component> itr = access.queryAll("treeitem").iterator();
        if (!Strings.isBlank(selectedRole.getImage())) {
            Map<String, Integer> map = StudioUtil.fromJson(selectedRole.getImage());
            while (itr.hasNext()) {
                Treeitem ti = (Treeitem) itr.next();
                if (ti.getValue() != null)
                    ti.setSelected(map.containsKey(ti.getValue()));
            }
        } else {
            while (itr.hasNext()) {
                Treeitem ti = (Treeitem) itr.next();
                if (ti.getValue() != null)
                    ti.setSelected(false);
            }
        }
    }

    @Override
    public void dispatch(Event event) {
        if (event.getTarget() == checkAll) {
            Iterator<Component> itr = access.queryAll("treeitem").iterator();
            while (itr.hasNext()) {
                Treeitem ti = (Treeitem) itr.next();
                if (ti.getValue() != null)
                    ti.setSelected(checkAll.isChecked());
            }
        } else if (event.getTarget() == rolesSearch) {
            if (event instanceof OpenEvent) {
                OpenEvent evt = (OpenEvent) event;
                val = (String) evt.getValue();
                rolesSearch.setValue(val);
            } else
                val = rolesSearch.getValue();
            if (Strings.isBlank(val))
                redraw(StudioApp.execute(new GetStudioRolesCmd()));
            else
                redraw(StudioApp.execute(new GetStudioRoleslikeCmd(val)));
        } else if (event.getTarget() == checkRev) {
            Iterator<Component> itr = access.queryAll("treeitem").iterator();
            while (itr.hasNext()) {
                Treeitem ti = (Treeitem) itr.next();
                if (ti.getValue() != null)
                    ti.setSelected(!ti.isSelected());
            }
        } else if (event.getTarget() instanceof Button) {
            if (event.getTarget().getId().equals("workbenchRole_button_studioRoleAdd")) {
                selectedRole = new RoleVo();
                selectedRole.setCode('C');
                key.setReadonly(false);
                setValue();
            } else if (event.getTarget().getId().equals("workbenchRole_button_studioRoleDelete")) {
                if (selectedRole == null) {
                    WebUtils.showError(Labels.getLabel("editor.select",
                            new String[]{Labels.getLabel("menu.studio.role")}));
                    return;
                }
                WebUtils.showConfirm(Labels.getLabel("button.delete"), this);
            } else if (event.getTarget().getId().equals("workbenchRole_button_studioRoleEdit")) {
                //if (selectedRole == null || selectedRole.getCode() != 'C') {
                /*if (selectedRole == null || selectedRole.getCode() != 'U') {
                    WebUtils.showError(Labels.getLabel("editor.select",
                            new String[]{Labels.getLabel("menu.studio.role")}));
                    return;
                }*/
                if (Strings.isBlank(key.getValue())) {
                    WebUtils.notEmpty(Labels.getLabel("entity.id"));
                    return;
                }
                if (Strings.isBlank(name.getValue())) {
                    WebUtils.notEmpty(Labels.getLabel("entity.name"));
                    return;
                }
                Iterator<Component> itr = access.queryAll("treeitem").iterator();
                Map<String, Integer> map = new HashMap<>();
                while (itr.hasNext()) {
                    Treeitem ti = (Treeitem) itr.next();
                    if (ti.isSelected())
                        map.put((String) ti.getValue(), 1);
                }
                if (map.isEmpty()) {
                    WebUtils.notEmpty(Labels.getLabel("menu.authorization"));
                    return;
                }
                selectedRole.setImage(StudioUtil.toJson(map));
                selectedRole.setId(key.getValue());
                selectedRole.setDesp(desp.getValue());
                selectedRole.setName(name.getValue());
                if (StudioApp.execute(event.getTarget(), new UpdateStudioRoleCmd(
                        selectedRole))) {
                    if (selectedRole.getCode() == 'C') {
                        if (Strings.isBlank(val) || selectedRole.getId().contains(val) || selectedRole.getName().contains(val) || selectedRole.getDesp().contains(val)) {
                            Listitem row = new Listitem();
                            row.setValue(selectedRole);
                            row.appendChild(new Listcell(selectedRole.getId()));
                            row.appendChild(new Listcell(selectedRole.getName()));
                            row.appendChild(new Listcell(selectedRole.getDesp()));
                            row.addEventListener(Events.ON_CLICK, this);
                            row.setSelected(true);
                            roleGrid.appendChild(row);
                        }
                    } else {
                        if (getSelectedRow() != null) {
                            Listitem row = getSelectedRow();
                            RoleVo roleVo = row.getValue();
                            if (roleVo.getId().equals(selectedRole.getId())) {
                                List<Listcell> labels = row.getChildren();
                                labels.get(1).setLabel(selectedRole.getName());
                                labels.get(2).setLabel(selectedRole.getDesp());
                            }
                        }
                    }
                    if (selectedRole.getCode() == 'C') {
                        WebUtils.showSuccess(Labels.getLabel("button.add")
                                + Labels.getLabel("menu.studio.role")
                                + selectedRole.getId());
                    }
                    if (selectedRole.getCode() == 'U') {
                        WebUtils.showSuccess(Labels.getLabel("button.eidt")
                                + Labels.getLabel("menu.studio.role")
                                + selectedRole.getId());
                    }
                    selectedRole.setCode('U');
                }
            }
        } else if (event.getName().equals(Events.ON_OK)) {
            selectedRole.setCode('D');
            if (StudioApp.execute(new UpdateStudioRoleCmd(selectedRole))) {
                if (getSelectedRow() != null) {
                    getSelectedRow().detach();
                }
                selectedRole = new RoleVo();
                selectedRole.setCode('C');
                setValue();
            }
        } else if (event.getTarget() instanceof Listitem) {
            Listitem row = (Listitem) event.getTarget();
            selectedRole = row.getValue();
            selectedRole.setCode('U');
            key.setReadonly(true);
            setValue();
        }
    }

    private Listitem getSelectedRow() {
        if (selectedRole == null || selectedRole.getCode() == 'C')
            return null;
        return roleGrid.getSelectedItem();
    }
}
